package com.duowan.cms.action;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.duowan.cms.common.util.NetUtil;
import com.duowan.cms.common.util.StringUtil;
import com.duowan.cms.dto.user.UserInfo;
import com.duowan.cms.dto.user.UserPowerInfo;
import com.duowan.cms.dto.user.UserStatus;
import com.duowan.cms.service.ip.IpService;
import com.duowan.cms.service.user.UserService;

@Controller
public class LoginController extends AbstractController {

    private static Logger logger = Logger.getLogger(LoginController.class);

    private static final String UDB_VALIDATE_URL = "http://webapi.duowan.com/api_udb2.php";
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private IpService ipService;

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String toIndex(HttpServletRequest request, HttpServletResponse response) throws IOException {
        return "/index";
    }
    
    @RequestMapping(value = "/login/udbLogin", method = RequestMethod.GET)
    public String udbLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        String ip = getRealIp(request);
        if(!ipService.isInnerIP(ip)){
            return "redirect:/login/toLogin.do?type=udbIpError";
        }
        
        
        Map<String, String> uParamsMap = new HashMap<String, String>();
        for(Cookie cookie : request.getCookies()){
            uParamsMap.put("COOKIE["+cookie.getName()+"]", cookie.getValue());
        }
        uParamsMap.put("HTTP_USER_AGENT", request.getHeader("User-Agent"));
        uParamsMap.put("HTTP_HOST", request.getHeader("Host"));
        uParamsMap.put("format", "json");
        
        try {
            String respStr = NetUtil.postHttpRequest(uParamsMap, UDB_VALIDATE_URL, 5);
            logger.info("udb登录接口返回信息：" + respStr);
            String[] udbInfo = getUdbLoginInfo(respStr);
            if(null != udbInfo && !StringUtil.hasOneEmpty(udbInfo[0],udbInfo[1])){
                return loginByUdbName(request, udbInfo[0]);
            }
        } catch (Exception e) {
            logger.warn("udb登录错误：", e);
        }
        return "redirect:/login/toLogin.do?type=udbError";
    }
    
    @RequestMapping(value = "/login/checkUdbName", method = RequestMethod.GET)
    public void checkUdbName(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        String udbName = request.getParameter("udbName");
        if(!StringUtil.isEmpty(udbName)){
            UserInfo user = userService.getByUdbName(udbName);
            if(null != user){
                response.getWriter().write("true");
            }else{
                response.getWriter().write("false");
            }
        }
    }
    
    private String loginByUdbName(HttpServletRequest request, String udbName){
        UserInfo userInfo = userService.getByUdbName(udbName);
        if (null != userInfo) {
            if (userInfo.getUserStatus() == UserStatus.NORMAL) {// 正常用户
                logger.info("用户[uid=" + userInfo.getUserId() + "]登入系统。");
                //为userInfo添加权限信息
                List<UserPowerInfo> userPowerInfoList = userService.getAllPowerByUyserId(userInfo.getUserId());
                userInfo.setAllChannelPowerInfo(userPowerInfoList);
                
                request.getSession().setAttribute("userInfo", userInfo);
                userInfo.setLastModifyTime(new Date());
                userService.updateUser(userInfo);
                // 只验证用户的合法性
                return "redirect:/index.do";
            } else {// 被冻结用户
                logger.info("用户[uid=" + userInfo.getUserId() + "]，被冻结，登录失败。");
                return "redirect:/login/toLogin.do?type=freeze";
            }
        } else {
            logger.info("系统查不到用户[udbName=" + udbName + "]。");
            return "redirect:/login/toLogin.do?type=udbNameError";
        }
    }
    
    /**
     * @param str
     * @return [0]--> username,[1]-->yyuid
     */
    private String[] getUdbLoginInfo(String str){
        Pattern p = Pattern.compile("\\{\"username\":\"(\\w+)\"\\s*,\\s*\"yyuid\":\"(\\w+)\"\\s*\\}");
        Matcher m = p.matcher(str);
        if(m.find()){
            String username = m.group(1);
            String yyuid = m.group(2);
            return new String[]{username, yyuid};
        }
        return null;

    }
    
    @RequestMapping(value = "/login/siteNote", method = RequestMethod.GET)
    public String toNote(HttpServletRequest request, HttpServletResponse response) throws IOException {
        return "/login/siteNote";
    }

    @RequestMapping(value = "/login/toLogin", method = RequestMethod.GET)
    public String toLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        String ip = getRealIp(request);
        if(ipService.isInnerIP(ip)){
            logger.info("来自内网ip:" + ip);
            request.setAttribute("innerIp", true);
        }
        
        String errorMessage = request.getParameter("type");
        if ("error".equals(errorMessage)) {
            request.setAttribute("errorMessage", "密码验证不成功，登录失败");
        } else if("freeze".equals(errorMessage)){
            request.setAttribute("errorMessage", "用户被冻结，请联系管理员");
        } else if("udbError".equals(errorMessage)){
            request.setAttribute("errorMessage", "udb登陆失败，请用发布器用户登陆");
        } else if("udbNameError".equals(errorMessage)){
            request.setAttribute("errorMessage", "udb账号未与发布器绑定，请用发布器用户登陆后在[个人信息]中绑定udb账号");
        } else if("udbIpErrop".equals(errorMessage)){
            request.setAttribute("errorMessage", "非内网ip无法使用udb登陆失败");
        }
        return "/login/login";
    }
    
    private String getRealIp(HttpServletRequest req) {

        String ip = req.getHeader("X-Forwarded-For");
        if(StringUtil.isEmpty(ip)) {
            return req.getRemoteAddr();
        }
        ip = ip.split(", ")[0].trim();
        if("127.0.0.1".equals(ip)) {
            return req.getRemoteAddr();
        }
        return ip;
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String userId = request.getParameter("userId");
        String password = request.getParameter("password");
        password = fetchPass(password);
        UserInfo userInfo = userService.getByUserIdAndPassword(userId, password);
        if (null != userInfo) {
            if (userInfo.getUserStatus() == UserStatus.NORMAL) {// 正常用户
                logger.info("用户[uid=" + userInfo.getUserId() + "]登入系统。");
                //为userInfo添加权限信息
                List<UserPowerInfo> userPowerInfoList = userService.getAllPowerByUyserId(userId);
                userInfo.setAllChannelPowerInfo(userPowerInfoList);
                
                request.getSession().setAttribute("userInfo", userInfo);
                userInfo.setLastModifyTime(new Date());
                userService.updateUser(userInfo);
                // 只验证用户的合法性
                return "redirect:/index.do";
            } else {// 被冻结用户
                logger.info("用户[uid=" + userId + "]，被冻结，登录失败。");
                return "redirect:/login/toLogin.do?type=freeze";
            }
        } else {
            logger.info("用户[uid=" + userId + "]，密码验证不成功，登录失败。");
            return "redirect:/login/toLogin.do?type=error";
        }
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("用户[ uid = " + ((UserInfo) request.getSession().getAttribute("userInfo")).getUserId() + "]登出系统。");
        request.getSession().removeAttribute("userInfo");
        return "redirect:/login/toLogin.do";
    }

    @RequestMapping(value = "/left", method = RequestMethod.GET)
    public String toLeft(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //String userId = request.getParameter("userId");
        //UserInfo userInfo = userService.getById(userId);
        UserInfo userInfo = (UserInfo)request.getSession().getAttribute("userInfo");
        List<UserPowerInfo> userPowerInfoList = userInfo.getAllChannelPowerInfo();//userService.getAllPowerByUyserId(userId);
        request.setAttribute("userPowerInfoList", userPowerInfoList);
        request.setAttribute("channelAmount", userPowerInfoList.size());
        return "/include/left";
    }

    @RequestMapping(value = "/head", method = RequestMethod.GET)
    public String toHead(HttpServletRequest request, HttpServletResponse response) throws IOException {
        return "/include/head";
    }


    @RequestMapping(value = "/toPageNotFoundPage", method = RequestMethod.GET)
    public String toPageNotFoundPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        return "/include/404";
    }

    @RequestMapping(value = "/toErrorPage", method = RequestMethod.GET)
    public String toErrorPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setAttribute("errorMessage", request.getParameter("errorMessage"));
        return "/include/custom_error";
    }

    /**
     * 	翻译加密过的密码
     */
    private static String fetchPass(String src) {
        String desc = "";
        String key = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if (src == null || src.trim().length() < 3)
            return desc;
        int len = key.indexOf(src.substring(src.length() - 1, src.length()));
        int index = key.indexOf(src.substring(src.length() - 2, src.length() - 1));
        return src.substring(index, index + len);
    }
}
